home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-05-03 | 6.6 KB | 201 lines | [TEXT/MPS ] |
- (* ****************************************************************
-
- UndoFolderIEnd.p
- Translated to MPW Pascal by Jim Merritt (jam)
- based on an original C routine by Raymond Lau.
-
- Copyright © 1992-93 Aladdin Systems, Inc. & Raymond Lau.
- All Rights Reserved.
-
- In combination with the associated make file (undoFolder.make),
- this source text produces an IEnd code-resource, which can
- be called by a Product Installer at the end of the installation
- process. Specifications for IBeg, IMid, and IEnd code resources
- are given in the documentation for the StuffIt Installer™.
-
- This subroutine performs the following functions:
-
- • Move everything within the user-specified destination folder
- into the parent of that folder (i.e., one level up).
- • If an item cannot be moved to the parent directory because
- another item there already has the same name, then rename the
- item to be moved, before actually moving it.
- • Finally, delete the emptied user-specified folder.
-
- CHANGE HISTORY:
-
- VER DATE ENGR DESCRIPTION
- 1 93.04.14 jam Initial version, based on Lau's
- original in C.
- 2 93.04.28 jam Pascal definitions of code resources were
- changed to be more in line with idiomatic
- usage. In particular, the name parameter
- was changed to a VAR Str255 instead of a
- value StringPtr. Various instances where
- name was used had to be changed to reflect
- the new sense of the parameter.
- 3 93.06.16 jam Pascal definitions of code resources were
- changed to replace BOOLEAN parameters and
- function return values with INTEGERs, and
- also to replace enumeration types and SETs
- with INTEGERs. This was made necessary
- when we discovered that certain Pascal
- compilers used very eccentric enumeration
- mechanisms, which were profoundly
- incompatible with the original C definitions
- at the machine-code level. The best
- compromise was to fall back to INTEGERs.
- 5 94.03.14 jam Modified DoAfterIntalling to observe new
- packages parameter. (NOTE: Version 4 was
- experimental and never published.)
-
- ****************************************************************** *)
- (*$Z+*) (* Allows linker to find DoAfterInstalling without declaring it
- in the interface *)
- UNIT IEnd;
-
- INTERFACE (* empty -- see $Z directive, above *)
-
- IMPLEMENTATION
- (* Putting a subroutine within a UNIT that has an empty
- IMPLEMENTATION is an oft-used method for creating
- a standalone code-resource in MPW Pascal.
- *)
-
- (* *********************** INCLUDES *************************** *)
- USES Types, (* for StringPtr, OSErr, noErr *)
- Errors, (* for fnfErr *)
- Memory, (* for BlockMove *)
- Files, (* for various filesystem calls and objects,
- including ioDirMask *)
- OSUtils, (* for SysBeep *)
- ToolUtils, (* for BitAnd *)
- Packages; (* for NumToString *)
-
- CONST
- IntFALSE= 0;
- IntTRUE= 1; (* (x <> IntFALSE) should be used to test for IntTRUE *)
- (* Use the constant IntTRUE only when you desire to assign a TRUE
- value to an INTEGER.
- *)
-
- (* ------------------------------------------------
- //
- // DoAfterInstalling
- //
- //
- // ------------------------------------------------ *)
- FUNCTION DoAfterInstalling( Canceled: INTEGER;
- vRefNum: INTEGER; parID: LONGINT;
- VAR name: Str255;
- packages: INTEGER ): INTEGER;
-
- CONST
- NameStrMaxLen= 32;
-
- VAR
- HRec: HParamBlockRec;
- DoneMovingFiles, DoneCheckingConflicts: BOOLEAN;
- i, j: INTEGER;
- sourcedir: LONGINT;
- cmpb: CMovePBRec;
-
- Strg: STRING[10];
- StringPtrToStrg: StringPtr; (* for type-coercion *)
- newname, sourcename: STRING[NameStrMaxLen];
- BEGIN (* DoAfterInstalling *)
- (* for type-coercion in the conflict-checking loop *)
- StringPtrToStrg := @Strg;
-
- (* Now, the real work begins. *)
- IF (Canceled = IntFALSE) THEN BEGIN
- HRec.ioNamePtr := @name;
- HRec.ioVRefNum := vRefNum;
- HRec.ioDirID := parID;
- HRec.ioFDirIndex := 0;
-
- IF (PBGetCatInfoSync(@HRec) <> noErr) THEN BEGIN
- (* Really weird! Nothing got unstuffed? *)
- Canceled := IntTRUE;
- END ELSE BEGIN
- sourcedir := HRec.ioDirID;
-
- IF (BitAnd(HRec.ioFlAttrib, ioDirMask) <> 0)
- THEN BEGIN
- i := 1;
- DoneMovingFiles := FALSE;
- REPEAT
-
- HRec.ioFDirIndex := 1;
- HRec.ioDirID := sourcedir;
- HRec.ioVRefNum := vRefNum;
- HRec.ioNamePtr := StringPtr(@sourcename);
-
- IF (PBGetCatInfoSync(@HRec) = noErr) THEN BEGIN
- j := 0;
- DoneCheckingConflicts := FALSE;
- REPEAT
- (* See if it exists in the level above. *)
- BlockMove(@sourcename,@newname,NameStrMaxLen);
- (*$R-*)
- IF (j <> 0) THEN BEGIN
- IF (ORD(newname[0]) > (NameStrMaxLen-4))
- THEN newname[0] := CHR(NameStrMaxLen-4);
- NumToString(j, StringPtrToStrg^);
- (*$R+*)
- newname := Concat(newname,'.');
- newname := Concat(newname, Strg);
- END;
- HRec.ioFDirIndex := 0;
- HRec.ioDirID := parID;
- HRec.ioVRefNum := vRefNum;
- HRec.ioNamePtr := StringPtr(@newname);
-
- IF (PBGetCatInfoSync(@HRec) = fnfErr) THEN BEGIN
- IF (J <> 0) THEN BEGIN
- (* hrumph -- check current level as well. *)
- HRec.ioFDirIndex := 0;
- HRec.ioDirID := sourcedir;
- HRec.ioVRefNum := vRefNum;
- HRec.ioNamePtr := StringPtr(@newname);
- DoneCheckingConflicts := (PBGetCatInfoSync(@HRec) = fnfErr);
- END ELSE DoneCheckingConflicts := TRUE;
- END;
-
- IF (NOT DoneCheckingConflicts) THEN J := J + 1;
- UNTIL DoneCheckingConflicts;
- IF (j <> 0) THEN BEGIN
- HRec.ioDirID := sourcedir;
- HRec.ioVRefNum := vRefNum;
- HRec.ioNamePtr := StringPtr(@sourcename);
- HRec.ioMisc := Ptr(@newname);
- IF (PBHRenameSync(@HRec) <> noErr)
- THEN BEGIN (* handle any error here *) END;
- END;
-
- cmpb.ioNamePtr := StringPtr(@newname);
- cmpb.ioVRefNum := vRefNum;
- cmpb.ioNewName := NIL;
- cmpb.ioNewDirID := parID;
- cmpb.ioDirID := sourcedir;
-
- IF (PBCatMoveSync(@cmpb) <> noErr)
- THEN BEGIN (* handle any error here *) END;
- END (* IF NOT PBGetCatInfoSync(@HRec) *)
- ELSE DoneMovingFiles := TRUE;
- UNTIL DoneMovingFiles;
-
- (* now delete the folder *)
- HRec.ioNamePtr := @name;
- HRec.ioVRefNum := vRefNum;
- HRec.ioDirID := parID;
- IF (PBHDeleteSync(@HRec) <> noErr)
- THEN BEGIN (* handle any error here *) END;
- END (* IF BitAnd... *);
- END (* IF THEN ELSE *);
- END (* IF (NOT Canceled) *);
-
- DoAfterInstalling := Canceled;
- END (* DoAfterInstalling *);
-
- END (* IEnd *).